home *** CD-ROM | disk | FTP | other *** search
- ;CHECK.COM for the IBM Personal Computer - 1986 by Jeff Prosise
- .8087 ;recognize 8087/80287 instructions
- code segment para public 'code'
- assume cs:code,ds:code
- org 100h
- begin: jmp check ;skip data area
- ;
- notice db ' Copyright 1986 Ziff-Davis Publishing Co.'
- notice_2 db ' Programmed by Jeff Prosise'
-
- keywords db 'MEMORY',0,'FILESIZE',0,'VIDEOCARD',0
- db 'MODEL',0,'8087',0,'80287',0
- db 'FILEFOUND',0,'FILETEXT',0,'DISKSPACE',0
- db 'VIDEOMODE',0,'TIME',0,'DAY',0,'MONTH',0
- db 'VERSION',0,'KEYBOARD',0,'KEYPRESS',0
- ;
- jump_table dw offset keypress ;vector dispatch table
- dw offset keyboard
- dw offset version
- dw offset month
- dw offset day
- dw offset time
- dw offset videomode
- dw offset diskspace
- dw offset filetext
- dw offset filefound
- dw offset mathproc
- dw offset mathproc
- dw offset model
- dw offset videocard
- dw offset filesize
- dw offset memory
- ;
- ibm db 'IBM' ;EGA signature
- parameter_count db ? ;number of command line parameters
- string_length dw 0 ;length of text string in bytes
- file_handle dw ? ;storage area for DOS file handle
- command_index dw ? ;storage for parsing index
- keyword_buffer dw offset endprog ;pointer to keyword buffer
- param1_buffer dw offset endprog+16 ;pointer to parameter buffer
- text_string dw offset endprog+144 ;pointer to text string buffer
- dta dw offset endprog+272 ;pointer to Disk Transfer Area
- control_bytes label byte ;byte accessor to control word
- control_8087 dw 0 ;8087/80287 control word
- ;
- errmsg1 db 13,10,'Invalid Keyword',13,10,'$'
- errmsg2 db 13,10,'Missing Parameter',13,10,'$'
- errmsg3 db 13,10,'Invalid Drive Specifier',13,10,'$'
- errmsg4 db 13,10,'Invalid String Specifier',13,10,'$'
- errmsg5 db 13,10,'File Not Found',13,10,'$'
- ;
- check proc near
- cld ;clear DF for string instructions
- call parse_line ;parse command line for entries
- cmp parameter_count,0 ;any parameters entered?
- jne check1 ;yes, then continue
- lea dx,errmsg2 ;no - load error msg address
- jmp error1 ;abort on error
- check1: lea si,keywords ;point SI to keyword list
- mov cx,16 ;number of reserved keywords
- check2: mov di,keyword_buffer ;point DI to keyword just entered
- check3: lodsb ;get character
- or al,al ;is it a zero byte?
- je match_found ;yes, then keywords match
- scasb ;compare it to byte in buffer
- je check3 ;loop back on match
- dec cx ;no match - decrement counter
- jcxz error_exit ;list scanned unsuccessfully
- check4: lodsb ;index SI to next word in list
- or al,al ;is this byte a zero?
- jne check4 ;no, try again
- jmp check2 ;SI set - try another keyword
- ;
- ;Execution comes here when the keyword entered on the command line matches one
- ;of the recognized keywords. The count in CX is translated into a pointer to
- ;the address of the routine to be vectored to.
- ;
- match_found: mov bx,cx ;get keyword number in BX
- dec bx ;decrement it by 1
- shl bx,1 ;multiply by two to form index
- jmp word ptr cs:[offset jump_table+bx] ;goto handler
- ;
- ;Execution comes here when an error is encountered.
- ;
- error_exit: lea dx,errmsg1 ;load address of error message
- error1: push ax ;save error return code in AL
- mov ah,9 ;DOS function - Print String
- int 21h ;print error message
- pop ax ;retrieve return code
- ;
- ;EXIT is the common point of exit for all routines in the program. A return
- ;code is set that can be read as the ERRORLEVEL parameter by batch processes.
- ;
- exit: mov ah,4Ch ;DOS function - Exit Program
- int 21h ;exit with return code
- check endp
- ;
- ;Model routine returns the machine ID byte of the computer being used.
- ;
- model proc near
- mov ax,0F000h ;set ES to ROM segment
- mov es,ax
- mov di,0FFFEh ;load DI with offset of ID byte
- mov al,es:[di] ;get machine ID byte into AL
- jmp exit ;exit
- model endp
- ;
- ;VideoMode routine returns the current video mode (0-16).
- ;
- videomode proc near
- mov ah,15 ;INT 10h function - Get Video Data
- int 10h ;get video mode in AL
- jmp exit ;exit
- videomode endp
- ;
- ;VideoCard routine returns a value indicating what kind of video adapter is
- ;being used in the system (0=MDA, 1=CGA, 2=EGA).
- ;
- videocard proc near
- mov dl,2 ;initialize DL
- mov bx,0C000h ;set ES to EGA BIOS segment
- mov es,bx
- mov di,1Eh ;set DI to IBM signature address
- lea si,ibm ;set SI to 'IBM' text
- mov cx,3 ;three bytes to check
- repe cmpsb ;compare the three bytes
- je card1 ;this is an EGA - jump to exit
- dec dl ;adjust DL for MDA or CGA
- mov ah,15 ;get current video mode
- int 10h
- cmp al,7 ;is it mode 7?
- jne card1 ;no, then this is a CGA
- dec dl ;zero DL for MDA
- card1: mov al,dl ;set AL for exit
- jmp exit ;and exit
- videocard endp
- ;
- ;Memory routine returns the number of 16K RAM modules present in the system.
- ;
- memory proc near
- int 12h ;get memory size from BIOS
- mov cl,4 ;set CL to 4 for shift
- shr ax,cl ;shift 4 times to divide by 16
- jmp exit
- memory endp
- ;
- ;FileFound returns 0 if the indicated file is found, 1 if it's not.
- ;
- filefound proc near
- cmp parameter_count,1 ;more than 1 parameter entered?
- ja filefnd1 ;yes, then continue
- lea dx,errmsg2 ;no, then get error msg address
- mov al,1 ;set AL to 1 to indicate failure
- jmp error1 ;and exit
- filefnd1: mov dx,param1_buffer ;point DX to filename
- mov ah,3Dh ;use DOS Open File function
- xor al,al ;set AL to 0 for read-only access
- int 21h ;attempt to open the file
- jnc filefnd2 ;open process succeeded
- mov al,1 ;open failed - set AL to 1
- jmp exit
- filefnd2: mov bx,ax ;get file handle in BX
- mov ah,3Eh ;use DOS Close File function
- int 21h ;close file just opened
- xor al,al ;zero AL for exit
- jmp exit
- filefound endp
- ;
- ;KeyBoard returns 1 if a key has been pressed, 0 if one has not.
- ;
- keyboard proc near
- mov ah,1 ;use BIOS to check buffer
- int 16h ;get status of keyboard buffer
- je kb1 ;empty if ZF set
- mov al,1 ;not empty - set AL to 1
- jmp exit
- kb1: xor al,al ;buffer empty - zero AL
- jmp exit
- keyboard endp
- ;
- ;KeyPress returns waits for a keypress (if one isn't already buffered) and
- ;returns its ASCII code.
- ;
- keypress proc near
- mov ah,0 ;use BIOS function to read keypress
- int 16h ;get keypress - ASCII code in AL
- jmp exit
- keypress endp
- ;
- ;Version returns the major number of the version of DOS in use.
- ;
- version proc near
- mov ah,30h ;use DOS Get Version function
- int 21h ;get version number
- jmp exit
- version endp
- ;
- ;DiskSpace returns the number of whole 16K blocks of free disk space from the
- ;indicated or default drive. AL is 0 on exit if an error is encountered. A
- ;return value of 255 means there are that many blocks or more free.
- ;
- diskspace proc near
- xor dl,dl ;set DL to 0 for default drive
- cmp parameter_count,1 ;only one parameter entered?
- je dspace1 ;yes, then use default drive
- mov si,param1_buffer ;set SI to parameter text
- lodsb ;get first character in parameter
- sub al,64 ;convert to DOS drive designator
- mov dl,al ;shift designator to DL
- lodsb ;get following character
- cmp al,':' ;is it a colon?
- je dspace1 ;yes, then continue
- lea dx,errmsg3 ;no, then load error msg address
- xor al,al ;set AL for failure
- jmp error1 ;exit on error
- dspace1: mov ah,36h ;use DOS Get Free Space function
- int 21h ;get disk information
- cmp ax,0FFFFh ;drive designator error?
- jne dspace2 ;no, then continue
- lea dx,errmsg3 ;abort on drive error
- xor al,al
- jmp error1
- dspace2: mul cx ;multiply to get bytes per cluster
- mul bx ;multiply again to get free bytes
- mov cx,14 ;set shift counter
- dspace3: shr dx,1 ;shift AX:DX right 14 bits
- rcr ax,1
- loop dspace3 ;loop until done
- or ah,ah ;is the MSB zero?
- je dspace4 ;yes, then continue
- mov al,255 ;no, then set AL to 255
- dspace4: jmp exit
- diskspace endp
- ;
- ;Time returns the current hour of the day (0-23).
- ;
- time proc near
- mov ah,44 ;get current time from DOS
- int 21h
- mov al,ch ;place hour in AL
- jmp exit
- time endp
- ;
- ;Day returns the current day of the month (1-31).
- ;
- day proc near
- mov ah,42 ;get current date from DOS
- int 21h
- mov al,dl ;put day in AL
- jmp exit
- day endp
- ;
- ;Month returns the current month number (1-12).
- ;
- month proc near
- mov ah,42 ;get date from DOS
- int 21h
- mov al,dh ;put month in AL
- jmp exit
- month endp
- ;
- ;FileText returns 0 if the specified string is found within the indicated
- ;file. A 1 is returned if the string is not contained within the file, if
- ;the file is not found, or if a syntax error is detected on the command line.
- ;
- filetext proc near
- cmp parameter_count,2 ;at least two parameters entered?
- je text1 ;yes, then continue
- lea dx,errmsg2 ;no, then abort
- mov al,1
- jmp error1
- text1: mov si,command_index ;point SI to end of second param
- mov di,text_string ;point DI to string buffer
- text2: lodsb ;get next character
- cmp al,32 ;is it a space character?
- je text2 ;yes, then go back for another
- cmp al,39 ;is it a quote mark?
- je text4 ;yes, then branch and continue
- cmp al,13 ;end-of-line marker?
- jne text3 ;no, it's an invalid character
- lea dx,errmsg2 ;abort - string missing
- mov al,1
- jmp error1
- text3: lea dx,errmsg4 ;abort - syntax error in string
- mov al,1
- jmp error1
- text4: lodsb ;get character in string
- cmp al,13 ;end-of-line marker?
- je text3 ;yes, then abort
- cmp al,39 ;quote mark?
- je text5 ;yes, then end of string reached
- stosb ;copy character to string buffer
- inc string_length ;increment length count
- jmp text4 ;go back for another character
- text5: cmp string_length,0 ;any characters in string?
- jne text6 ;yes, then continue
- lea dx,errmsg4 ;no, then abort
- mov al,1
- jmp error1
- text6: mov dx,param1_buffer ;point DX to filename
- mov ah,3Dh ;open the file
- xor al,al
- int 21h
- jnc text7 ;continue if open succeeded
- lea dx,errmsg5 ;abort if it failed
- mov al,1
- jmp error1
- text7: mov file_handle,ax ;save file handle
- text8: mov dx,dta ;point DX to Data Transfer Area
- mov cx,0C000h ;specify C000h bytes to be read
- mov bx,file_handle ;get DOS file handle
- mov ah,3Fh ;DOS function - Read Block
- int 21h ;read block from file on disk
- cmp ax,string_length ;enough bytes read in to compare?
- jb not_found ;no, then terminate
- mov bx,ax ;save actual bytes read in BX
- mov cx,ax ;prepare CX for comparison loop
- sub cx,string_length
- inc cx
- mov di,dta ;point DI to block just read
- text9: push cx ;save loop counter
- push di ;save start index
- mov cx,string_length ;prepare to compare string
- mov si,text_string ;point SI to string text
- repe cmpsb ;compare while equal
- pop di ;restore saved registers
- pop cx
- je text_found ;match found if ZF set
- inc di ;increment starting index
- loop text9 ;loop until entire block examined
- cmp bx,0C000h ;was end-of-file reached?
- jne not_found ;yes, then exit - string not found
- mov ah,42h ;DOS function - Move File Pointer
- mov al,1 ;method code - current pos + offset
- mov cx,0FFFFh ;form negative integer in DX:CX
- mov dx,string_length ;get string length in low word
- not dx ;form complement
- add dx,1 ;form two's complement
- adc cx,0 ;carry into high word (CX)
- mov bx,file_handle ;get file handle
- int 21h ;move file pointer back
- jmp text8 ;read another block from disk
- text_found: xor al,al ;text found - zero AL
- jmp close_file
- not_found: mov al,1 ;text not found - set AL to 1
- close_file: push ax ;save return code in AL
- mov ah,3Eh ;close file before exiting
- mov bx,file_handle
- int 21h
- pop ax ;restore AL
- jmp exit
- filetext endp
- ;
- ;FileSize returns the length in kilobytes of the specified file. A value of
- ;255 means the file is 255K or greater in length. 0 is returned if the file
- ;cannot be found.
- ;
- filesize proc near
- cmp parameter_count,1 ;more than 1 parameter entered?
- ja size1 ;yes, then continue
- lea dx,errmsg2 ;no filename - abort
- xor al,al
- jmp error1
- size1: mov dx,param1_buffer ;point DX to ASCIIZ filename
- mov ah,3Dh ;use DOS Open File function
- xor al,al ;open for reading only
- int 21h ;open the file
- jnc size2 ;continue if open succeeded
- lea dx,errmsg5 ;abort if it did not
- xor al,al
- jmp error1
- size2: push ax ;save file handle on stack
- mov bx,ax ;get file handle in BX
- mov ah,42h ;use DOS to move file pointer
- mov al,2 ;method code - EOF + offset
- xor cx,cx ;specify 0 offset in DX:CX
- xor dx,dx
- int 21h ;move file pointer to EOF
- pop bx ;get file handle
- push ax ;save EOF address
- push dx
- mov ah,3Eh ;close file
- int 21h
- pop dx ;retrieve address
- pop ax
- mov cl,10 ;prepare CL for shift
- size3: shr dx,1 ;shift AX:DX right 10 bits
- rcr ax,1
- loop size3
- or dx,dx ;DX = 0 ?
- jne max_length ;no, filesize > 255K
- or ah,ah ;AH = 0 ?
- jne max_length ;no, filesize > 255K
- jmp exit ;length in AL
- max_length: mov al,255 ;set AL to 255 for exit
- jmp exit
- filesize endp
- ;
- ;Mathproc returns a 1 if neither an 8087 nor an 80287 math coprocessor is
- ;detected in the system or a 0 if one of them is.
- ;
- mathproc proc near
- fninit ;initialize (set control word)
- fnstcw control_8087 ;write control word to memory
- cmp control_bytes[1],3 ;control word correctly written?
- je found_8087 ;yes, then 8087/80287 is there
- mov al,1 ;no coprocessor - set AL to 1
- jmp exit
- found_8087: xor al,al ;zero AL
- jmp exit
- mathproc endp
- ;
- ;------------------------------------------------------------------------------
- ;PARSE_LINE parses the command line for the first two parameters entered and
- ;writes them into their respective storage buffers.
- ;------------------------------------------------------------------------------
- parse_line proc near
- mov parameter_count,0 ;zero count of entries
- mov si,81h ;set SI to start of text
- call next_parameter ;index to next parameter
- jc parse_exit ;exit if there's not one
- mov di,keyword_buffer ;set DI for output
- call get_parameter ;parse parameter to buffer
- inc parameter_count ;increment count
- call next_parameter ;index to next parameter
- jc parse_exit ;exit if there's not one
- mov di,param1_buffer ;set DI for output
- call get_parameter ;get next parameter
- inc parameter_count ;increase count
- parse_exit: mov command_index,si ;save SI for additional parsing
- ret ;and exit
- parse_line endp
- ;
- ;------------------------------------------------------------------------------
- ;NEXT_PARAMETER indexes SI to the next non-space character.
- ;Entry: DS:SI - current character | Exit: CF clear - character found
- ; | CF set - end-of-line reached
- ;------------------------------------------------------------------------------
- next_parameter proc near
- cmp byte ptr [si],13 ;end-of-line reached?
- je end_of_line ;yes, then jump
- cmp byte ptr [si],32 ;space character (delimiter)?
- jne no_space ;no, then character found
- inc si ;advance pointer
- jmp next_parameter ;check another character
- no_space: clc ;clear CF for exit
- ret
- end_of_line: stc ;set CF to indicate EOL
- ret
- next_parameter endp
- ;
- ;------------------------------------------------------------------------------
- ;GET_PARAMETER transfers the command line parameter indexed by SI into the
- ;designated buffer area, capitalizing lowercase characters in the process and
- ;terminating the string with a zero for ASCIIZ representation.
- ;Entry: DS:SI - parameter address
- ; ES:DI - buffer address
- ;------------------------------------------------------------------------------
- get_parameter proc near
- cmp byte ptr [si],13 ;end-of-line reached?
- je end_get ;yes, then we're done
- cmp byte ptr [si],32 ;space delimiter encountered?
- je end_get ;yes, then we're done
- lodsb ;get the character
- cmp al,97 ;is it a lowercase character?
- jb getparam1
- cmp al,122
- ja getparam1
- and al,0DFh ;yes, then capitalize it
- getparam1: stosb ;buffer the character
- jmp get_parameter ;loop back for more
- end_get: xor al,al ;zero AL
- stosb ;end string with 0 delimiter
- ret
- get_parameter endp
- ;
- endprog label byte ;start of buffer area
- ;
- code ends
- end begin
-